package edu.mercer.sse.plainpdf;

import java.util.Map;
import java.util.logging.Level;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import com.google.common.base.Function;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Maps;

import edu.mercer.sse.annotations.Fulfills;
import edu.mercer.sse.log.LoggerCustom;
import static com.google.common.base.Preconditions.*;

/**
 * Extract any command line variables for a utility.<p>
 * 
 * Example excerpt from <code>config.xml</code>:<p>
 * 
 * <code>
 * &#60;entry key="PDFCROP_ARGUMENTS"&#62; --margins {MARGIN_BP} --clip 
 * 	{FILE_IN} {FILE_OUT} &#60;/entry&#62;
 * </code>
 * <p>
 * 
 * Example: <code>{FILE_IN}</code><p>
 * 
 * Returns Map containing keys such as: <code>FILE_IN</code>
 * 
 * Empty Map returned if no argument variables found in command line.<p>
 * 
 * @see Function
 */

public class ParseCommandLineVarsFunction 

	implements Function<String, Map<String, String>> 
{
	/** 
	 * Command line variables and their values; i.e., 'FILE_IN', 'mypic.tiff' 
	 */
	
	private final Map<String,String> _varsFnd = Maps.newHashMap();
	
	/**
	 * RegEx Pattern of Command line variables in argument String.
	 */
	
	private final Pattern _commandLineVarPat = Pattern.compile(
			  "[\\{]{1}" 
			+ "(?<CmdVar>[A-Z_]{1,20})"
			+ "[\\}]{1}"); 
	
	
	@Fulfills("Function")
	@Override
	public ImmutableMap<String, String> apply( final String commandLine ) 
	{
		final Matcher commandLineVarMtchr = _commandLineVarPat.matcher(
				commandLine );
		
		while( commandLineVarMtchr.find() )
		{
			final Integer varCount = commandLineVarMtchr.groupCount();
			
			for( Integer ct=1; ct <= varCount; ct++ )
			{
				String varName = commandLineVarMtchr.group(ct);
				
				String diagosticStr = " index: " + ct + " in: " + commandLine;
				
				checkNotNull( varName, "null var name," + diagosticStr );
				
				checkArgument( !varName.isEmpty(), "could not parse group "
						+ "name," + diagosticStr );

				/* each command line variable is initialized as empty String */
				
				_varsFnd.put( varName, "" );

				LoggerCustom.obtainLog("ParseCommandLineVarsFunction",
						Level.FINE).fine( "found " + varName 
												   + " for group index "
												   + ct
												   + " in " 
												   + commandLine );

			}//for
			
		}//if
		
		if( _varsFnd.isEmpty() )
		{
			LoggerCustom.obtainLog("ParseCommandLineVarsFunction",Level.FINE)
				.fine( "did not find any command line variables for: " 
					   + commandLine );
			
		}//if
		
		return _varsFnd.isEmpty() ? 
				
				new ImmutableMap.Builder<String,String>().build() : 
					
				ImmutableMap.copyOf( _varsFnd );
	
	}//method


}//class
